<template>
  <div class="scroll" ref="scrollRef">
    <slot></slot>
  </div>
</template>

<script setup>
import { onMounted, ref } from 'vue';
import BetterScroll from '@better-scroll/core';
import ObserveDom from '@better-scroll/observe-dom';
import Pulldown from '@better-scroll/pull-down';
import Pullup from '@better-scroll/pull-up';

// 自动监听容器变化
BetterScroll.use(ObserveDom);
// 上拉刷新
BetterScroll.use(Pulldown);
// 上拉加载
BetterScroll.use(Pullup);

const props = defineProps({
  // 1. probeType 为 0，在任何时候都不派发 scroll 事件，
  // 2. probeType 为 1，仅仅当手指按在滚动区域上，每隔 momentumLimitTime 毫秒派发一次 scroll 事件，
  // 3. probeType 为 2，仅仅当手指按在滚动区域上，一直派发 scroll 事件，
  // 4. probeType 为 3，任何时候都派发 scroll 事件，包括调用 scrollTo 或者触发 momentum 滚动动画
  probeType: {
    type: Number,
    default: 3
  },
  // 点击列表是否派发click事件
  click: {
    type: Boolean,
    default: true
  },
  scrollX: {
    type: Boolean,
    default: false
  },
  scrollY: {
    type: Boolean,
    default: true
  },
  // 是否派发下拉刷新事件
  pulldown: {
    type: [Boolean, Object],
    default: false
  },
  // 是否派发上拉加载事件
  pullup: {
    type: [Boolean, Object],
    default: false
  },
  // 保留原生滚动，可选值：'vertical' | 'horizontal'
  // 如果模拟横向滚动，而纵向的滚动还是保留原生滚动，则设置为vertical，反之为horizontal
  eventPassthrough: {
    type: String,
    default: ''
  },
  // 指定 wrapper 对应索引的子元素作为 content，进行滚动
  specifiedIndexAsContent: {
    type: Number,
    default: 0
  }
});

const emit = defineEmits(['pullDown', 'pullUp']);

let scroll = ref();
let scrollRef = ref();

onMounted(() => {
  initialize();
});

// 初始化滚动
function initialize() {
  const scrollEl = scrollRef.value;
  if (!scrollEl) return;
  scroll.value = new BetterScroll(scrollEl, {
    observeDOM: true,
    pullDownRefresh: props.pulldown,
    pullUpLoad: props.pullup,
    probeType: props.probeType,
    click: props.click,
    scrollX: props.scrollX,
    scrollY: props.scrollY,
    eventPassthrough: props.eventPassthrough,
    specifiedIndexAsContent: props.specifiedIndexAsContent
  });
  // console.log('scrollView initialized: ', scroll);

  if (props.pulldown) {
    scroll.value.on('pullingDown', () => {
      emit('pullDown');
    });
  }

  if (props.pullup) {
    scroll.value.on('pullingUp', () => {
      emit('pullUp');
    });
  }
}

// 代理better-scroll的refresh方法
function refresh() {
  scroll.value && scroll.value.refresh();
}

// 代理better-scroll的scrollTo方法
function scrollTo() {
  scroll.value && scroll.value.scrollTo.apply(scroll.value, arguments);
}

// 代理better-scroll的scrollToElement方法
function scrollToElement() {
  scroll.value && scroll.value.scrollToElement.apply(scroll.value, arguments);
}

// 代理better-scroll的finishPullDown方法
function finishPullDown() {
  scroll.value && scroll.value.finishPullDown();
}

// 代理better-scroll的finishPullUp方法
function finishPullUp() {
  scroll.value && scroll.value.finishPullUp();
}

// 暴露方法，以便外部能够访问到
defineExpose({
  refresh,
  scrollTo,
  scrollToElement,
  finishPullDown,
  finishPullUp
});
</script>

<style lang="less">
.scroll {
  overflow: hidden;
}
</style>
